package com.xja.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xja.exception.CustomException;
import com.xja.mapper.EmployeeMapper;
import com.xja.model.dto.EmployeeLoginDTO;
import com.xja.model.dto.EmployeeRegisterDTO;
import com.xja.model.entity.Employee;
import com.xja.model.vo.resp.EmployeeLoginVO;
import com.xja.service.IEmployeeService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.xja.constant.CommonConstant.*;

/**
 * <p>
 * 用户信息表 服务实现类
 * </p>
 *
 * @author caijg
 * @since 2025-06-08
 */
@Service
@RequiredArgsConstructor
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements IEmployeeService {

    private final StringRedisTemplate redisTemplate;
    private final RabbitTemplate rabbitTemplate;

    @Override
    public EmployeeLoginVO login(EmployeeLoginDTO employeeLoginDTO) {
        // 1.检查是否存在该用户
        Employee employee = this.query().eq("username", employeeLoginDTO.getUsername()).one();
        if (employee == null) {
            throw new CustomException("账号不存在，请注册", 400);
        }
        // 2.校验密码
        if (!SecureUtil.md5(employeeLoginDTO.getPassword()).equals(employee.getPassword())) {
            throw new CustomException("密码错误", 400);
        }

        if (employee.getStatus() == 0) {
            throw new CustomException("该用户已被禁用", 400);
        }
        // 3.验证成功，生成token
        String token = IdUtil.fastSimpleUUID();
        // 存入redis
        redisTemplate.opsForValue()
                .set(EMPLOYEE_LOGIN_TOKEN_PREFIX + token
                        , employee.getId().toString()
                        , EMPLOYEE_LOGIN_TTL, TimeUnit.HOURS);
        // 4.封装VO
        EmployeeLoginVO loginVO = new EmployeeLoginVO();
        loginVO.setToken(token);
        loginVO.setId(employee.getId());
        loginVO.setUsername(employee.getUsername());
        loginVO.setNickname(employee.getNickname());
        loginVO.setRole(employee.getRole());
        loginVO.setAvatar(employee.getAvatar());

        // 5.返回结果
        return loginVO;
    }

    @Override
    public void sendSmsCode(String phone) {
        // 1.确保手机号存在
        Employee employee = this.query().eq("phone", phone).one();
        if (employee == null) {
            throw new CustomException("手机号不存在", 400);
        }
        // 2.生成验证码
        String code = RandomUtil.randomNumbers(6);
        // 3.发送验证码（异步）
        Map<String, String> data = Map.of("phone", phone, "code", code);
        rabbitTemplate.convertAndSend("sms.topic", "success", data);
        // 4.保存验证码到Redis
        redisTemplate.opsForValue()
                .set(EMPLOYEE_PHONE_CODE_PREFIX + phone
                        , code
                        , 5, TimeUnit.MINUTES);
    }

    @Override
    public EmployeeLoginVO loginByPhone(String phone, String code) {
        // 1.检查是否存在该用户
        Employee employee = this.query().eq("phone", phone).one();
        if (employee == null) {
            throw new CustomException("手机号不存在！", 400);
        }
        // 2.校验验证码
        String storedCode = redisTemplate.opsForValue().get(EMPLOYEE_PHONE_CODE_PREFIX + phone);
        if (StrUtil.isEmpty(storedCode) || !storedCode.equals(code)) {
            throw new CustomException("验证码错误！", 400);
        }
        if (employee.getStatus() == 0) {
            throw new CustomException("该用户已被禁用", 400);
        }

        // 3.验证成功，生成token
        String token = IdUtil.fastSimpleUUID();
        redisTemplate.opsForValue()
                .set(EMPLOYEE_LOGIN_TOKEN_PREFIX + token
                        , employee.getId().toString()
                        , EMPLOYEE_LOGIN_TTL, TimeUnit.HOURS);
        // 4.封装VO
        EmployeeLoginVO loginVO = new EmployeeLoginVO();
        loginVO.setToken(token);
        loginVO.setId(employee.getId());
        loginVO.setUsername(employee.getUsername());
        loginVO.setNickname(employee.getNickname());
        loginVO.setRole(employee.getRole());
        loginVO.setAvatar(employee.getAvatar());

        // 5.删除验证码
        redisTemplate.delete(EMPLOYEE_PHONE_CODE_PREFIX + phone);

        return loginVO;
    }

    @Override
    public void logout(HttpServletRequest request) {
            // 1.获取用户携带的token
            String token = request.getHeader("Authorization");
            // 2.删除redis中对应的token
            redisTemplate.delete(EMPLOYEE_LOGIN_TOKEN_PREFIX + token);
    }
}